import { ModelStore } from './ModelStore';
import { mockModel } from '../mock';

/**
 * ModelLoader class - Responsible for loading the application model from the server.
 */
export class ModelLoader {
  private _modelData: any = null;
  private _isLoaded: boolean = false;  private _useMockData: boolean = false;

  /**
   * Create a new ModelLoader instance
   * @param useMockData Whether to use mock data instead of loading from the server
   */
  constructor(useMockData: boolean = false) {
    this._useMockData = useMockData;
  }

  /**
   * Load the application model from the specified API URL
   * @param apiUrl The URL to the XAF WebAPI endpoint
   */  public async loadModel(apiUrl: string): Promise<void> {
    try {
      if (this._useMockData) {
        // Use mock data instead of loading from the server
        console.log('Using mock application model data');
        this._modelData = { ...mockModel };
        this._isLoaded = true;
        
        // Process the model
        this._processModel();
        return;
      }

      // Add a trailing slash if needed
      const baseUrl = apiUrl.endsWith('/') ? apiUrl : `${apiUrl}/`;
      
      // Fetch the application model from the server
      const response = await fetch(`${baseUrl}api/model`);
      
      if (!response.ok) {
        throw new Error(`Failed to load model: ${response.statusText}`);
      }
      
      this._modelData = await response.json();
      this._isLoaded = true;
      
      console.log('Application model loaded successfully');
      
      // Process the model
      this._processModel();
    } catch (error) {
      console.error('Failed to load application model:', error);
      throw error;
    }
  }

  /**
   * Get the raw model data
   */
  public get modelData(): any {
    return this._modelData;
  }

  /**
   * Check if the model is loaded
   */
  public get isLoaded(): boolean {
    return this._isLoaded;
  }

  /**
   * Process the loaded model to prepare it for use
   */
  private _processModel(): void {
    if (!this._modelData) {
      return;
    }
    
    // Process business objects
    if (this._modelData.businessObjects) {
      this._processBusinessObjects(this._modelData.businessObjects);
    }
    
    // Process views
    if (this._modelData.views) {
      this._processViews(this._modelData.views);
    }
    
    // Process navigation
    if (this._modelData.navigation) {
      this._processNavigation(this._modelData.navigation);
    }
  }

  /**
   * Process business object definitions
   * @param businessObjects Business object definitions from the model
   */
  private _processBusinessObjects(businessObjects: any[]): void {
    // Store business object definitions for later use
    ModelStore.getInstance().setBusinessObjects(businessObjects);
  }

  /**
   * Process view definitions
   * @param views View definitions from the model
   */
  private _processViews(views: any[]): void {
    // Store view definitions for later use
    ModelStore.getInstance().setViews(views);
  }
  /**
   * Process navigation definitions
   * @param navigation Navigation definitions from the model
   */
  private _processNavigation(navigation: any): void {
    // Store navigation definitions for later use
    console.log('Processing navigation data:', navigation);
    ModelStore.getInstance().setNavigation(navigation);
    console.log('Navigation data set in ModelStore:', ModelStore.getInstance().navigation);
  }
}
